home *** CD-ROM | disk | FTP | other *** search
/ Educational Software Cooperative 4 / Educational Software Cooperative 4.iso / lights22 / weep.cpr / SS_CRAWL.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-06-22  |  23.5 KB  |  869 lines

  1. {$A-,B-,D+,F-,G+,I-,K-,L+,N-,P-,Q-,R-,S-,T-,V+,W-,X+,Y+}
  2. {$M 8192,8192}
  3. {************************************************}
  4. {                                                }
  5. {   Turbo Pascal for Windows                     }
  6. {   Screen Saver Demo for Windows                }
  7. {   Copyright (c) 1992 by Thomas H÷vel           }
  8. {   Requires 'The Lights Go Down'                }
  9. {                                                }
  10. {************************************************}
  11.  
  12. { This file is bi-lingual: German and English
  13.   Diese Datei ist zweisprachig: Deutsch und Englisch
  14.  
  15.   This file contains a sample LGD module.
  16.   You'll find further information in API.HLP.
  17.   Define ENGLISH to compile the English version.
  18.  
  19.   LGD searches all SS_*.LGD files in its own directory.
  20.   Note: If you add an Debug=1 entry in the LGD section of WEEP.INI,
  21.     LGD will search for SS_*.DLL instead of *.LGD. This is useful
  22.     for TPW programmers!
  23.  
  24.   The DLL (which will be renamed to LGD in the retail version) contains
  25.   4 function:
  26.     ScreenSaverID      index 17
  27.     ScreenSaverOptions index 18
  28.     ScreenSaver        index 19
  29.     ScreenSaverAbout   index 20
  30.  
  31.   ScreenSaverID identifies the screen saver. It reports name and description
  32.     and functions supported by the saver.
  33.   ScreenSaver is the function that actual draws. It registers a Window class,
  34.     opens a windows and waits for WM_QUIT.
  35.   ScreenSaverAbout may be empty. It gives the author a good chance to make
  36.     his name known to the user.
  37.   ScreenSaverOptions may be empty, too. Allows the user to change screen saver
  38.     parameters which should be saved in an .INI-file.
  39.  
  40.   Die Parameter der einzelnen Funktionen werden weiter unten beschrieben.
  41.   ************************************************************************
  42.  
  43.   Diese Datei zeigt das Grundgeruest eines LGD-Bildschirmschoners.
  44.   Weitere Informationen finden Sie in API.HLP
  45.  
  46.   LGD sucht nach Dateien, die dem Schema SS_*.LGD entsprechen. Die .LGD-
  47.   Dateien sind normale .DLLs, die lediglich umbenannt wurden.
  48.  
  49.   Tip für TPW: In der Datei WEEP.INI kann im Abschnitt [LGD] der Eintrag
  50.   Debug=1 eingefügt werden. Danach sucht LGD nach SS_*.DLL, d.h. zum Testen
  51.   muß die DLL nicht mehr umbenannt werden.
  52.  
  53.   Grundsaetzlicher Aufbau:
  54.  
  55.   Die .DLL (spaeter SS_*.LGD genannt) stellt folgende vier Funktionen
  56.   zur Verfügung:
  57.     ScreenSaverID      index 17
  58.     ScreenSaverOptions index 18
  59.     ScreenSaver        index 19
  60.     ScreenSaverAbout   index 20
  61.  
  62.   ScreenSaverID dient zur Identifikation. Sie übergibt Namen und Beschreibung
  63.     des Schoners und zeigt an, welche Funktionen unterstützt werden.
  64.   ScreenSaver ist der eigentliche Schoner. In der Regel wird diese Funktion
  65.     eine Fensterklasse eintragen, ein Fenster oeffnen und auf WM_QUIT warten.
  66.   ScreenSaverAbout ist eine optionale Funktion. Sie ermöglicht dem Autor
  67.     eines Schoner-Moduls eine angemessene Selbstdarstellung.
  68.   ScreenSaverOptions erlaubt dem Benutzer, bestimmte Parameter des Schoners
  69.     zu veraendern. Diese Parameter sollten in einer .INI-Datei gespeichert
  70.     werden. Diese Funktion ist optional.
  71.  
  72.   Die Parameter der einzelnen Funktionen werden weiter unten beschrieben.
  73.  
  74. }
  75.  
  76. {$c preload}
  77.  
  78. {$define COL256}  { unterstⁿtzung fⁿr farbpalette mit 256 farben }
  79.           { use color palettes with 256 colors }
  80.  
  81. { $define RUN}   { RUN: standalone (.EXE), or .DLL }
  82. {$ifndef RUN}
  83. library ss_Crawl;
  84. {$endif}
  85.  
  86.  
  87. {$ifdef ENGLISH}
  88.   {$d Crawler: LGD Screen Saver (c) 1993 Thomas H÷vel}
  89.   {$r se_crawl.res}
  90. {$else}
  91.   {$d Crawler: Bildschirmschoner (c) 1993 Thomas H÷vel}
  92.   {$r ss_crawl.res}
  93. {$endif}
  94.  
  95. uses
  96. {$ifdef COL256}
  97.   ssCommon,            { definitionen fⁿr farbpalette / definitions for color palette }
  98. {$endif}
  99.   WinTypes, WinProcs, lm_lgd, strings
  100. {$ifdef USESOUNDS}
  101.   , iSounds
  102. {$endif}
  103.   ;
  104.  
  105. const AppName = 'LGD_Crawler';
  106.       Ini     = 'WEEP.INI';
  107. {$ifdef ENGLISH}
  108.       HELPTEXT : array[0..24]of char = 'Gummyworms'' Options'#0;
  109. {$else}
  110.       HELPTEXT : array[0..24]of char = 'Optionen von Crawler'#0;
  111. {$endif}
  112.       HELPFILE = 'LGD.HLP';
  113.  
  114. var
  115.     lEndTime: LongInt;   { zeitdauer (fⁿr Randomizer), period (for Randomizer) }
  116.     lTime, lTmp: LongInt;
  117.     fExit: LongInt;      { ende durch eingabe ?, ended by user action? }
  118. {$ifdef COL256}
  119.     pif: PInterFace;     { zeiger auf parameterstruktur (von LGD ⁿbergeben) }
  120.              { parameters received from LGD }
  121. {$endif}
  122.     cxClient, cyClient: integer;
  123.  
  124. const MAXTAIL = 100;
  125.       MAXWORM = 50;
  126.       __MAXTAIL:integer = 20;
  127.       __MAXWORM:integer = 20;
  128.       __TURBO: integer = 0;
  129.  
  130. type
  131.      TPosition = record
  132.        x, y: integer;
  133.      end;
  134.       
  135.      TailType = record
  136.        head, tail: integer;
  137.        TailPos: array [1..MAXTAIL] of TPosition;
  138.      end;
  139.  
  140.      CrawlerType = record
  141.        xPos, yPos: integer;
  142.        Dir: integer;
  143.        l, m, d: TColorRef;
  144.        Tail: TailType;
  145.      end;
  146.  
  147. var Crawlers: array [1..MAXWORM] of CrawlerType;
  148. {$ifdef USESOUNDS}
  149.   cSoundTime:integer;
  150. {$endif}
  151.  
  152.  
  153.  
  154. var fLocalHelp: boolean;
  155.  
  156. function Options(Dialog: HWnd; Message, WParam: Word;
  157.   LParam: Longint): Bool; export;
  158. var trans: bool;
  159. begin
  160.   Options := True;
  161.   case Message of
  162.     wm_InitDialog:
  163.       begin
  164.     fLocalHelp := FALSE;
  165.     SetDlgItemInt (Dialog, 103, __MAXWORM, FALSE);
  166.     SetDlgItemInt (Dialog, 104, __MAXTAIL, FALSE);
  167.     SetDlgItemInt (Dialog, 105, __TURBO, FALSE);
  168. {$ifdef USESOUNDS}
  169.     if THSndVersion > 0 then
  170.       ShowWindow (GetDlgItem (dialog, 199), sw_normal);
  171. {$endif}
  172.     Exit;
  173.       end;
  174.     wm_Command:
  175.       if (WParam = 1) or (WParam = id_Cancel) then
  176.     begin
  177.       if (wParam = 1) then
  178.         begin
  179.           __MAXWORM := GetDlgItemInt (Dialog, 103, @trans, FALSE);
  180.           __MAXTAIL := GetDlgItemInt (Dialog, 104, @trans, FALSE);
  181.           __TURBO   := GetDlgItemInt (Dialog, 105, @trans, FALSE);
  182.           if __MAXTAIL < 2 then
  183.         __MAXTAIL := 2
  184.           else if __MAXTAIL > MAXTAIL then
  185.         __MAXTAIL := MAXTAIL;
  186.           if __MAXWORM < 1 then
  187.         __MAXWORM := 1
  188.           else if __MAXWORM > MAXWORM then
  189.         __MAXWORM := MAXWORM;
  190.           if __TURBO < 0 then
  191.         __TURBO := 0
  192.           else if __TURBO > 9999 then
  193.         __TURBO := 9999;
  194.         end;
  195.       if fLocalHelp then
  196.         WinHelp (Dialog, HelpFile, help_Quit, 0);
  197.       EndDialog(Dialog, 1);
  198.       Exit;
  199.     end
  200.       else if (wParam = 102) then
  201.     begin
  202.       WinHelp (dialog, HELPFILE, help_Key, LONGINT (@HELPTEXT));
  203.       fLocalHelp := TRUE;
  204.       exit;
  205.     end
  206. {$ifdef USESOUNDS}
  207.       else if (wParam = 199) then
  208.     begin
  209.       THSndOptions (AppName, dialog);
  210.     end
  211. {$endif}
  212.     ;
  213.   end;
  214.   Options := False;
  215. end;
  216.  
  217.  
  218.  
  219.  
  220.  
  221. Procedure DrawSegment (dc:hdc; xPos, yPos: integer; l,m,d: TColorRef);
  222. var x, y: integer;
  223.     lb:TLogBrush;
  224.     Brush: hBrush;
  225.     Pen: hPen;
  226. begin
  227.   dec (xPos, 3);  { adresse des mittelpunkts ⁿbergeben }
  228.   dec (yPos, 3);  { received address of center }
  229.  
  230.   lb.lbStyle := bs_Solid;
  231.   lb.lbColor := m;
  232.   lb.lbHatch := 0;
  233.   Brush := CreateBrushIndirect (lb);
  234.  
  235.   Brush := SelectObject (dc, Brush);
  236.   Pen := SelectObject (dc, GetStockObject (NULL_PEN));
  237.   Rectangle (dc, xPos + 2, yPos + 2, xPos + 8, yPos + 8);
  238.   DeleteObject (SelectObject (dc, Brush));
  239.   Pen := SelectObject (dc, CreatePen (ps_Solid, 1, l));
  240.   MoveTo (dc, xPos + 1, yPos + 6);
  241.   LineTo (dc, xPos + 1, yPos + 1);
  242.   LineTo (dc, xPos + 8, yPos + 1);
  243.   MoveTo (dc, xPos, yPos + 2);
  244.   LineTo (dc, xPos, yPos + 7);
  245.   MoveTo (dc, xPos + 2, yPos);
  246.   LineTo (dc, xPos + 7, yPos);
  247.   DeleteObject (SelectObject (dc, Pen));
  248.   Pen := SelectObject (dc, CreatePen (ps_Solid, 1, d));
  249.   MoveTo (dc, xPos + 1, yPos + 7);
  250.   LineTo (dc, xPos + 7, yPos + 7);
  251.   LineTo (dc, xPos + 7, yPos + 1);
  252.   MoveTo (dc, xPos + 2, yPos + 8);
  253.   LineTo (dc, xPos + 7, yPos + 8);
  254.   MoveTo (dc, xPos + 8, yPos + 2);
  255.   LineTo (dc, xPos + 8, yPos + 7);
  256.   DeleteObject (SelectObject (dc, Pen));
  257. end;
  258.  
  259. Procedure InitCrawlers;
  260. var i, j: integer;
  261. begin
  262.   for j := 1 to __MAXWORM do
  263.     with Crawlers [j] do
  264.       begin
  265.     for i := 1 to __MAXTAIL do
  266.       begin
  267.         Tail.TailPos [i].x := -17;
  268.         Tail.TailPos [i].y := -17;
  269.       end;
  270.     xPos := random (cxClient);
  271.     yPos := random (cyClient);
  272.     dir  := random (16 * 4);
  273.     Tail.tail := 1;
  274.     Tail.head := __MAXTAIL;
  275.     if (pif <> nil) then
  276.       begin
  277.         i := random (7);
  278.         l := PaletteIndex (ColorIndexesColorScales [i * 8 + 7]);
  279.         m := PaletteIndex (ColorIndexesColorScales [i * 8 + 5]);
  280.         d := PaletteIndex (ColorIndexesColorScales [i * 8 + 3]);
  281.       end
  282.     else
  283.       begin
  284.         i := random (7);
  285.         case i of
  286.           0: begin
  287.            l := RGB (255, 255, 255); { grau / grey}
  288.            m := RGB (192, 192, 192);
  289.            d := RGB (128, 128, 128);
  290.          end;
  291.           1: begin
  292.            l := RGB (255, 255, 0); { gelb / yellow }
  293.            m := RGB (192, 192, 0);
  294.            d := RGB (128, 128, 0);
  295.          end;
  296.           2: begin
  297.            l := RGB (0, 255, 255); { cyan }
  298.            m := RGB (0, 192, 192);
  299.            d := RGB (0, 128, 128);
  300.          end;
  301.           3: begin
  302.            l := RGB (0, 0, 255);   { blau / blue }
  303.            m := RGB (0, 0, 192);
  304.            d := RGB (0, 0, 128);
  305.          end;
  306.           4: begin
  307.            l := RGB (255, 0, 0);   { rot / red}
  308.            m := RGB (192, 0, 0);
  309.            d := RGB (128, 0, 0);
  310.          end;
  311.           5: begin
  312.            l := RGB (255, 0, 255);   { magenta }
  313.            m := RGB (192, 0, 192);
  314.            d := RGB (128, 0, 128);
  315.          end;
  316.           6: begin
  317.            l := RGB (0, 255, 0);   { grⁿn / green }
  318.            m := RGB (0, 192, 0);
  319.            d := RGB (0, 128, 0);
  320.          end;
  321.         end;                           { german and english share the same roots ... }
  322.       end;
  323.       end;
  324. end;
  325.  
  326. Procedure MoveCrawlers (dc: hDC);
  327. var i,j:integer;
  328. begin
  329.   for i := 1 to __MAXWORM do
  330.     with Crawlers [i] do
  331.       begin
  332.     DrawSegment (dc, Tail.TailPos [Tail.Tail].x, Tail.TailPos [Tail.Tail].y, 0, 0, 0);
  333.     DrawSegment (dc, xPos, yPos, l, m, d);
  334.     Tail.TailPos [Tail.Head].x := xPos;
  335.     Tail.TailPos [Tail.Head].y := yPos;
  336.     inc (Tail.Head);
  337.     if Tail.Head > __MAXTAIL then
  338.       Tail.Head := 1;
  339.     inc (Tail.Tail);
  340.     if Tail.Tail > __MAXTAIL then
  341.       Tail.Tail := 1;
  342.     case Dir div 4 of
  343.       0: begin inc (xPos, 6); end;
  344.       1: begin inc (xPos, 4); inc (yPos, 2); end;
  345.       2: begin inc (xPos, 3); inc (yPos, 3); end;
  346.       3: begin inc (xPos, 2); inc (yPos, 4); end;
  347.       4: begin                inc (yPos, 6); end;
  348.       5: begin dec (xPos, 2); inc (yPos, 4); end;
  349.       6: begin dec (xPos, 3); inc (yPos, 3); end;
  350.       7: begin dec (xPos, 4); inc (yPos, 2); end;
  351.       8: begin dec (xPos, 6); end;
  352.       9: begin dec (xPos, 4); dec (yPos, 2); end;
  353.      10: begin dec (xPos, 3); dec (yPos, 3); end;
  354.      11: begin dec (xPos, 2); dec (yPos, 4); end;
  355.      12: begin                dec (yPos, 6); end;
  356.      13: begin inc (xPos, 2); dec (yPos, 4); end;
  357.      14: begin inc (xPos, 3); dec (yPos, 3); end;
  358.      15: begin inc (xPos, 4); dec (yPos, 2); end;
  359.     end;
  360.     j := integer (random (5)) - 2;
  361.     dir := dir + j;
  362.     if xPos >= cxClient then
  363.       begin
  364.         xPos := cxClient-1;
  365.         dir := 8 * 4;
  366.       end;
  367.     if xPos < 0 then
  368.       begin
  369.         xPos := 0;
  370.         dir := 0;
  371.       end;
  372.     if yPos >= cyClient then
  373.       begin
  374.         yPos := cyClient -1;
  375.         dir := 12 * 4;
  376.       end;
  377.     if yPos < 0 then
  378.       begin
  379.         yPos := 0;
  380.         dir := 4 * 4;
  381.       end;
  382.     dir := dir and 63;
  383.       end;
  384. end;
  385.  
  386. { WindowProc des Bildschirmschoners }
  387. { In der Regel wird der Schoner über WM_TIMER bzw. über PeekMessage bestimmte
  388.   Zeichenaktionen ausloesen.
  389. }
  390. { Screen Saver's WindowProc }
  391. { Typically the screen saver will draw something on WM_TIMER messages or
  392.   using PeekMessage.
  393. }
  394.  
  395.  
  396. function WindowProc(Window: HWnd; Message, WParam: Word;
  397.   LParam: Longint): Longint; export;
  398. var
  399.   hMen: hMenu;
  400.   fFlag: Bool;
  401.   w: Word;
  402.   ps: TPaintStruct;
  403.   dc: HDC;
  404.   hOldPal: hPalette;
  405.   lRet: LongInt;
  406. begin
  407.   WindowProc := 0;
  408.   if (LgdDefProc (lRet, window, Message, wParam, lParam)) then
  409.     begin
  410.       WindowProc := lRet;
  411.       exit;
  412.     end;
  413.  
  414.   case Message of
  415.     wm_Paint:
  416.       begin
  417.     dc := BeginPaint (window, ps);
  418. {$ifdef COL256}
  419. (*      keine aktion bei wm_Paint
  420.     if pif <> nil then
  421.       begin
  422.         hOldPal := SelectPalette (dc, pif^.hPal, FALSE);
  423.         RealizePalette(dc);                    
  424.       end;
  425.           { hier: eigene zeichenroutinen einbauen }
  426.           { may add own drawing routines here }
  427.     if pif <> nil then
  428.       SelectPalette (dc, hOldPal, FALSE);
  429. *)
  430. {$endif}
  431.     EndPaint (window, ps);
  432.     exit;
  433.       end;
  434.  
  435.     wm_QUERYNEWPALETTE:
  436.       begin
  437.     if pif <> nil then
  438.       begin
  439.         dc := GetDC (window);
  440.         hOldPal := SelectPalette (dc, pif^.hPal, FALSE);
  441.         lRet := RealizePalette(dc);
  442.         SelectPalette (dc, hOldPal, FALSE);
  443. (*          the screen is either black or not erased - so do nothing now
  444.         "normal" applications would invalidate to redraw the window *)
  445. (*          bildschirm ist schwarz oder durchsichtig - eine applikation wⁿrde jetzt neu zeichnen 
  446.         if lRet > 0 then
  447.           InvalidateRect (window, nil, FALSE);*)
  448.         ReleaseDC (window, dc);
  449.       end
  450.     else
  451.       lRet := 0;
  452.     WindowProc := lRet;
  453.     exit;
  454.       end;
  455.  
  456.     wm_PaletteChanged:
  457.       begin
  458.     if (pif <> nil) and (wParam <> Window) then
  459.       begin
  460.         dc := GetDC (window);
  461.         hOldPal := SelectPalette (dc, pif^.hPal, FALSE);
  462.         lRet := RealizePalette(dc);
  463.         SelectPalette (dc, hOldPal, FALSE);
  464. (*          see note above *)
  465. (*          bildschirm ist schwarz oder durchsichtig - eine applikation wⁿrde jetzt neu zeichnen 
  466.         if lRet > 0 then
  467.           InvalidateRect (window, nil, FALSE);*)
  468.         ReleaseDC (window, dc);
  469.       end
  470.     else
  471.       lRet := 0;
  472.     WindowProc := lRet;
  473.     exit;
  474.       end;
  475.  
  476.     wm_Create:
  477.       begin
  478.       end;
  479.  
  480.     wm_EraseBkgnd:
  481.       begin
  482.     WindowProc := 1;
  483.     exit;
  484.       end;
  485.  
  486.    wm_Size:
  487.       begin
  488.     cxClient := LOWORD (lParam);
  489.     cyClient := HIWORD (lParam);
  490.     exit;
  491.       end;
  492.  
  493.     wm_Timer:
  494.       begin
  495.     if GetCurrentTime >= lEndTime then
  496.       begin
  497.         fExit := 0;             { normal timeout - randomizer continues }
  498.         DestroyWindow (window);
  499.         exit;
  500.       end;
  501. {$ifdef USESOUNDS}
  502.     dec (cSoundTime);
  503.     if cSoundTime < 0 then
  504.       begin
  505.         THSndRandom (AppName, FALSE);
  506.         cSoundTime := 10 + random (10);
  507.       end;
  508. {$endif}
  509.       end;
  510.  
  511.     wm_KillFocus:
  512.       begin
  513.     if fExit = -1 then
  514.       begin    { ende vorbereiten }
  515.         PostMessage (window, wm_Close, 0, 0);
  516.       end;
  517.       end;
  518.  
  519.  
  520.     wm_KeyDown,          { jeder tastendruck beendet den Saver }
  521.     wm_Close,            { any key terminates screen saver }
  522.     wm_lButtonDown,
  523.     wm_mButtonDown,
  524.     wm_rButtonDown:
  525.       begin
  526.     fExit := 1;   { randomizer mu▀ zwischen timeout und abbruch unterscheiden k÷nnen! }
  527.               { tells randomizer to exit (no timeout) }
  528.     DestroyWindow (window);
  529.     exit;
  530.       end;
  531.  
  532.     wm_Destroy:
  533.       begin
  534.     KillTimer (window, 1000);
  535.     PostQuitMessage(0);
  536.     Exit;
  537.       end;
  538.   end;
  539.   WindowProc := DefWindowProc(Window, Message, WParam, LParam);
  540. end;
  541.  
  542.  
  543.  
  544. Procedure ReadProfile;
  545. begin
  546.   __MAXWORM := GetPrivateProfileInt (appname, 'Anzahl', 10, Ini);
  547.   __MAXTAIL := GetPrivateProfileInt (appname, 'LΣnge', 10, Ini);
  548.   __TURBO := GetPrivateProfileInt (appname, 'lDelay', 20, Ini);
  549. end;
  550.  
  551. Procedure WriteProfile;
  552. var s:string;
  553. begin
  554.   str (__MAXWORM, s);
  555.   s := s + #0;
  556.   WritePrivateProfileString (AppName, 'Anzahl', @s[1], Ini);
  557.   str (__MAXTAIL, s);
  558.   s := s + #0;
  559.   WritePrivateProfileString (AppName, 'LΣnge', @s[1], Ini);
  560.   str (__TURBO, s);
  561.   s := s + #0;
  562.   WritePrivateProfileString (AppName, 'lDelay', @s[1], Ini);
  563. end;
  564.  
  565.  
  566.  
  567.  
  568.  
  569. { ScreenSaver - duration: Laufzeit (in Sekunden), <= 0 -> unendlich
  570.         Flags   : reserviert (pointer to interface structure)
  571. }
  572. { ScreenSaver - duration: time to execute (in seconds), <= 0 -> endless
  573.         Flags   : reserved (pointer to interface structure)
  574. }
  575.  
  576. Function ScreenSaver (duration: LongInt; Flags:LongInt): LongInt;
  577. {$ifndef RUN}
  578. export;
  579. {$endif}
  580. var
  581.   Window: HWnd;
  582.   Message: TMsg;
  583.   f:boolean;
  584.   cCursor, i: integer;
  585.   dc: hDC;
  586.   hOldPal: hPalette;
  587. const
  588.   WindowClass: TWndClass = (
  589.     style: cs_HREDRAW + cs_VREDRAW;
  590.     lpfnWndProc: @WindowProc;
  591.     cbClsExtra: 0;
  592.     cbWndExtra: 0;
  593.     hInstance: 0;
  594.     hIcon: 0;
  595.     hCursor: 0;
  596.     hbrBackground: 0;
  597.     lpszMenuName: nil;
  598.     lpszClassName: AppName);
  599. begin
  600.   Randomize;
  601.   ReadProfile;
  602.   fExit := -1;
  603. {$ifdef COL256}
  604.   pif := pointer (flags);
  605.   if pif <> nil then
  606.     if (pif^.lLevel <> 0) or
  607.        (pif^.lMagic <> $12348765) then
  608.       pif := nil;     { struktur nicht erkannt / unknown structure}
  609. {$endif}
  610.  
  611.   if HPrevInst = 0 then
  612.   begin
  613.     WindowClass.hInstance := HInstance;
  614.     WindowClass.hIcon := 0;
  615.     WindowClass.hCursor := LoadCursor(0, idc_Cross);
  616.     WindowClass.hbrBackground := GetStockObject(black_Brush);
  617.     if not RegisterClass(WindowClass) then
  618.     ;
  619.   end;
  620.   if (pif <> nil) and (pif^.lCaller = 1) then  { von LGD gerufen / caller is LGD }
  621.     begin
  622.       Window := CreateWindow(
  623.     AppName,
  624.     AppName,
  625.     ws_PopUp or ws_Border
  626.     or ws_Visible,
  627.     0,
  628.     0,
  629.     1,
  630.     1,
  631.     0,
  632.     0,
  633.     HInstance,
  634.     nil);
  635.       UpdateWindow(Window);
  636.     end
  637.   else
  638.     begin                        { caller is randomizer }
  639.       Window := CreateWindow(
  640.     AppName,
  641.     AppName,
  642.     ws_PopUp or ws_border
  643.     or ws_Visible or ws_maximize,
  644.     0,
  645.     0,
  646.     1,
  647.     1,
  648.     0,
  649.     0,
  650.     HInstance,
  651.     nil);
  652.       UpdateWindow(Window);
  653.     end;
  654.  
  655. {  SetWindowPos (Window, 0, -1, -1,
  656.         GetSystemMetrics (sm_cxScreen)+2,
  657.         GetSystemMetrics (sm_cyScreen)+2,
  658.         swp_noZOrder);
  659.  
  660.   ShowWindow (window, sw_Normal);}
  661.  
  662.   cCursor := 0;
  663.   repeat
  664.     i := ShowCursor (false);
  665.     inc (cCursor);
  666.   until i < 0;
  667.  
  668.   if duration > 0 then
  669.     lEndTime := GetCurrentTime + duration * 1000
  670.   else
  671.     lEndTime := $7fffffff;
  672.   lTime := ThTickCount;
  673.  
  674.   cxClient := GetSystemMetrics (sm_cxScreen); 
  675.   cyClient := GetSystemMetrics (sm_cyScreen);
  676.   InitCrawlers;
  677.  
  678. {$ifdef USESOUNDS}
  679.   cSoundTime := 0;
  680. {$endif}
  681.   SetTimer (window, 17, 1000, nil);
  682.  
  683.   f := TRUE;
  684.   while f do
  685.     begin
  686.       if PeekMessage (Message, 0, 0, 0, pm_REMOVE) then
  687.     begin
  688.       if Message.message = wm_Quit then
  689.         f := false
  690.       else
  691.         begin
  692.           TranslateMessage(Message);
  693.           DispatchMessage(Message);
  694.         end
  695.     end
  696.       else
  697.     begin
  698.       if not IsZoomed (window) then
  699.         PostMessage (window, wm_syscommand, sc_zoom, 0)
  700.       else
  701.       if fExit = -1 then
  702.         begin
  703.           lTmp := ThTickCount;
  704.           if (lTmp >= lTime + __TURBO) then
  705.         begin
  706.           lTime := lTmp;
  707.           dc := GetDC (window);
  708.           if pif <> nil then
  709.             begin
  710.               hOldPal := SelectPalette (dc, pif^.hPal, FALSE);
  711.               RealizePalette(dc);
  712.             end;
  713.           MoveCrawlers (dc);
  714.           if pif <> nil then
  715.             SelectPalette (dc, hOldPal, FALSE);
  716.           releaseDC (window, dc);
  717.         end
  718.         end;
  719.     end;
  720.   end;
  721.  
  722.  
  723.   while cCursor > 0 do
  724.     begin
  725.       ShowCursor (true);
  726.       dec (cCursor);
  727.     end;
  728.  
  729.   UnregisterClass (AppName, hInstance);
  730.   ScreenSaver := fExit;
  731. end;
  732.  
  733.  
  734. { ScreenSaverID - Identifikation des Schoners
  735.     Parameter:
  736.       wMagic    : muß bei der Rückkehr einen bestimmten Wert enthalten ($6874)
  737.       fFunctions: Bit 0  About-Funktion wird unterstützt
  738.           Bit 1  Options-Funktion wird unterstützt
  739.           Bit 2  Bildschirm darf bei Aufruf nicht schwarz sein
  740.           Bit 3  Hinterläßt einen schwarzen Bildschirm
  741.       achName   : Name des Schoners - daß erste Zeichen des Namens wird nicht
  742.           angezeigt, es legt bloß die Sortierung fest.
  743.       cchName   : Länge des Puffers für achName
  744.       achDesc   : Beschreibung des Schoners, bis max. ca. 8 Zeilen a 30 Zeichen
  745.           Beschreibung kann #10 (\n) (Zeilenvorschub) enthalten
  746.       cchDesc   : Länge des Puffers für Beschreibung
  747. }
  748. { ScreenSaverID - identifies the screen saver
  749.     Parameters:
  750.       wMagic    : set to magic ID number ($6874)
  751.       fFunctions: Bit 0  has an About function
  752.           Bit 1  has an Options function
  753.           Bit 2  requires non-blank screen on start
  754.           Bit 3  leaves blank screen on termination
  755.       achName   : saver name - first character is not shown, used for sorting only
  756.       cchName   : length of achName buffer
  757.       achDesc   : description of the saver, max. 8 lines with 30 chars. each (approx.)
  758.           may contain #10 (\n) line feed characters
  759.       cchDesc   : length of achDesc buffer
  760. }
  761.  
  762.  
  763. Procedure ScreenSaverID (var wMagic:integer;
  764.              var fFunctions:LongInt;
  765.                  achName:pchar;
  766.                  cchName:integer;
  767.                  achDesc:pchar;
  768.                  cchDesc:integer);
  769. export;
  770. begin
  771.   wMagic := $6874;
  772.   fFunctions := 16+4+2+1;  { 1: about, 2:options, 3:both }
  773.               { 4: non-blank (nicht-leerer bildschirm erforderlich }
  774.               { 8: hinterlΣ▀t leeren bildschirm }
  775.               { 4: non-blank (requires non-blank screen }
  776.               { 8: leaves screen blank }
  777.               {16: help in lgd.hlp available (not for 3rd party savers }
  778.   { das erste zeichen des namens wird nicht angezeigt, es legt
  779.     lediglich die sortierung fest. }
  780.   { first char is used for sorting only - it's not displayed
  781.     should be identical with the first visible character }
  782. {$ifdef ENGLISH}
  783.   StrLCopy (achName, 'GGummyworms', cchName - 1);
  784.   StrLCopy (achDesc, 'Gummyworms:'#10#10'Screen saver with support for 256 colours.'#10#10+
  785.              'The full program will list from the SDK\PAS sub directory!'#10,
  786.         cchDesc - 1);
  787. {$else}
  788.   StrLCopy (achName, 'CCrawler', cchName - 1);
  789.   StrLCopy (achDesc, 'Crawler:'#10#10'Bildschirmschoner mit 256-Farben-Unterstⁿtzung'#10#10'Quelltext (Pascal) liegt bei!'#10,
  790.         cchDesc - 1);
  791. {$endif}
  792. end;
  793.  
  794. { ScreenSaverOptions - der uebergebene Fensterhandle sollte als ParentWindow
  795.     für die Dialogbox benutzt werden 
  796.              - the window handle should be used as parent window }
  797. Procedure ScreenSaverOptions (window: hWND);
  798. export;
  799. var Proc: TFarProc;
  800. begin
  801.   ReadProfile;
  802.   Proc := MakeProcInstance(@Options, HInstance);
  803.   DialogBox(HInstance, 'OPTIONBOX', Window, Proc);
  804.   FreeProcInstance(Proc);
  805.   WriteProfile;
  806. end;
  807.  
  808.  
  809. { ScreenSaverAbout - Parameter wie bei ScreenSaverOptions
  810.            - refer to ScreenSaverOptions for parameters }
  811. Procedure ScreenSaverAbout (window: hWND);
  812. export;
  813. begin
  814. {$ifdef ENGLISH}
  815.   {$ifdef SHARE}
  816.   LgdAboutBox (window, 0,
  817.                        'Gummyworms',
  818.                        '⌐1992-95 Thomas H÷vel Software'#10+
  819.                        'Saturnstr. 45, 53842 Troisdorf, Germany'#10+
  820.                        'All Rights reserved!',
  821.                        FALSE, 3);
  822.   {$else}
  823.   LgdAboutBox (window, 0,
  824.                        'Gummyworms',
  825.                        '⌐1992-95 Thomas H÷vel Software'#10+
  826.                        'Saturnstr. 45, 53842 Troisdorf, Germany'#10+
  827.                        'All Rights reserved!',
  828.                        TRUE, 3);
  829.   {$endif}
  830. {$else}
  831.   {$ifdef SHARE}
  832.   LgdAboutBox (window, 0,
  833.                        'Crawler',
  834.                        '⌐1993-95 Thomas H÷vel Software'#10+
  835.                        'Saturnstra▀e 45, 53842 Troisdorf, Deutschland'#10+
  836.                        'Alle Rechte vorbehalten!',
  837.                        FALSE, 3);
  838.   {$else}
  839.   LgdAboutBox (window, 0,
  840.                        'Crawler',
  841.                        '⌐1993-95 Thomas H÷vel Software'#10+
  842.                        'Saturnstra▀e 45, 53842 Troisdorf, Deutschland'#10+
  843.                        'Alle Rechte vorbehalten!',
  844.                        TRUE, 3);
  845.   {$endif}
  846. {$endif}
  847. (*
  848. {$ifdef ENGLISH}
  849.   messagebox (window, 'Saver module for ''The Lights Go Down'''#10'(C) 1993 Leo Minor', 'Gummyworms', mb_Ok or mb_ApplModal);
  850. {$else}
  851.   messagebox (window, 'Beispiel zu ''The Lights Go Down'''#10'(C) 1993 Leo Minor', 'Crawler', mb_Ok or mb_ApplModal);
  852. {$endif}
  853. *)
  854. end;
  855.  
  856. {$ifndef RUN}
  857. exports
  858.   ScreenSaverID      index 17,
  859.   ScreenSaverOptions index 18,
  860.   ScreenSaver        index 19,
  861.   ScreenSaverAbout   index 20;
  862. {$endif}
  863.  
  864. begin
  865. {$ifdef RUN}
  866.   ScreenSaver (20, 0);  { demo fⁿr ca. 20 sekunden / run for 20 seconds }
  867. {$endif}
  868. end.
  869.